/**
 * Created by kouen on 2017/8/26.
 */

import * as echarts from 'echarts';
import 'echarts/lib/chart/line';
// 引入提示框组件、标题组件、工具箱组件。
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/title';
import 'echarts/lib/component/toolbox';

import React from 'react';
import { render } from 'react-dom';
import App from './App.js'


/**
 * 1. 按下TAB， 通过接口查询, 将查询到的数据返回到search_window
 * 2. 支持双击=>替换包含$字符的字符串(顺序替换，只替换一个)
 * 3. 如果中查询到一个，则直接替换.
**/
$("#formula_text").keydown((e)=> {
    let self = $("#formula_text");
    let window = $("#search_window");

    if (e.keyCode === 9 && self[0].value.indexOf(":") !== -1){
        // 避免重复按下TAB
        window.html('');

        let word = self[0].value.split(' ').pop();
        for (let line of self[0].value.split('\n')){
            if (line.indexOf(":") !== -1){
                let start_pos = line.indexOf(":");
                let length = line.indexOf(" ", start_pos) - start_pos;
                if (length >= 0)
                    word = line.substr(start_pos, length);
                else
                    word = line.substr(start_pos);
                break;
            }
        }
        console.log(word);
        $.get(`/config/query/primary/?q=${word}`, (result)=>{
            if (result.length > 1){
                for (let item of result){
                    window.append(`<button id="sw_btn_${item.id}" style="width: 100%; border:0; background-color: #FFF">${item.name}</button>`)
                    $(`#sw_btn_${item.id}`).click((e)=>{
                        SetText(self[0], e.currentTarget.innerText, ":");
                        self[0].focus();
                        window.html('');
                    });
                }
            }else if (result.length === 1){
                SetText(self[0], result[0].name, ":");
                self[0].focus();
            }

        });
        return false;
    }
});
$("#search_table").keydown((e)=>{
    let self = $("#search_table");
    if (e.keyCode === 13){
        FlushTable(self[0].value);
    }
});
/**
 1. 保存， 通过数据接口提交到后台, 根据按钮上的id控制是否是已存在数据(data_id)
 2. 删除，后端删除数据
 3. 清空，将名称和公式的文本框清空, 相等于建立新项目，移除data_id
 4. 测试，打开输入框并且输入数据，进行计算。
**/
$("#save_btn").click(()=>{
    let url_keyword = GetDBName();
    let name = $("#name_text")[0].value;
    let formula = $("#formula_text")[0].value.replace(/\n/g, '|');

    let data_id = $("#save_btn").attr('data_id');
    if (data_id !== undefined){
        $.post(`/config/commit/update/${url_keyword}/`, {id: data_id, name: name, formula: formula}, (res)=>{
            if (res.code === 0){
                FlushTable();
                alert('修改成功');
            }
        });
    }else{
        $.post(`/config/commit/insert/${url_keyword}/`, {name: name, formula: formula}, (res)=>{
            if (res.code === 0){
                FlushTable();
                alert('插入成功');
            }
        });
    }
});
$("#clear_btn").click(()=>{
    FlushTable();
});
$("#delete_btn").click(()=>{
    let item_id = $("#save_btn").attr('data_id');
    if (item_id !== undefined && GetDBName() !== undefined){
        $.get(`/config/commit/delete/${GetDBName()}/${item_id}/`, ()=>{
            alert("删除成功");
            FlushTable();
        })
    }
});
/**
 * 校验文本是否为空
 * tips：提示信息
 * 使用方法：$("#id").validate("提示文本");
 * @itmyhome
 */
$.fn.validate = function(tips){
    if($(this).val() === "" || $.trim($(this).val()).length === 0){
        alert(tips + "不能为空！");
        throw SyntaxError(); //如果验证不通过，则不执行后面
    }
};
/**
 * 测试请求
 */
$("#modal_clean").click(()=>{
    $("#modal_text_code").val("");
    let mode = $("#modal_mode_time")[0].value;
    if (mode === 'history') {
        $("#modal_mode_time_args1").val("2018-01-01");
        $("#modal_mode_time_args2").val("2018-06-01");
    }else if(mode === 'random'){
        $("#modal_mode_time_args1").val("2018-01-01");
        $("#modal_mode_time_args2").val("100");
    }else{
        $("#modal_mode_time_args1").val("100");
        $("#modal_mode_time_args2").val("");
    }
    $("#modal_sell").val("0,100");
    $("#modal_buy").val("0,100");
    $("#modal_money").val("100000");
    $("#name_text").val("");
    $("#formula_text").val("");
    $("#match_show_code").val("");
});
$("#modal_test").click(()=>{
    ResetTable();
    $("#quota_area").css("display", "none");
    $("#quota_show_code").val("");
    $("#quota_code")[0].innerHTML = "";
    $("#chart_quota")[0].innerHTML = "";
    $("#match_show_code").val("");
    let args = GetModalData();
    $.post(`/config/simulate/`, args);
    FlushSimulationResult(args);
    $("#match_area").css("display", "none");
});
$("#modal_match").click(()=>{
    $("#match_area").css("display", "none");
    $("#match_show_code").val("");
    $("#match_code")[0].innerHTML = "";
    let args = GetModalData();
    let max_count = parseInt($("#modal_text_code").val());
    if (max_count >= 10){
        max_count = 10;
    }
    $.post(`/config/match/`, args);
    FlushMarchResult(args, max_count);
});
$("#complete").click(()=>{
    let data_id = $("#save_btn").attr('data_id');
    if (data_id !== undefined) {
        $.post(`/config/complete/`, {code: 'all', quota: data_id, date: 'all'});
    }
});
$("#recal").click(()=>{
    let data_id = $("#save_btn").attr('data_id');
    let code = $("#quota_history_code").val();
    if (data_id !== undefined) {
        if (code === "" || code === undefined){
            code = "all";
        }
        $.post(`/config/recal/`, {quota: data_id, code: code});
    }
});
$("#quota_history").click(()=>{
    let data_id = $("#save_btn").attr('data_id');
    let code = $("#quota_history_code").val();
    if (data_id !== undefined && code !== "" && code !== undefined && code.length === 6) {
        console.log(data_id, code);
        $.post(`/config/quota_history/`, {quota: data_id, code: code}, (data)=>{
            if (data.ret === false){
                alert("没有计算好..");
                return;
            }
            let myChart = echarts.init(document.getElementById("chart"));
            let option = {
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'cross',
                        label: {
                            backgroundColor: '#283b56'
                        }
                    }
                },
                toolbox: {
                    show: true,
                    feature: {
                        dataView: {readOnly: false},
                        restore: {},
                        saveAsImage: {}
                    }
                },
                xAxis: {
                    type: 'category',
                    data: data.xAxis
                },
                yAxis: [
                    {
                        type: 'value',
                        scale: true,
                        precision: 2,
                        splitNumber: 9,
                        boundaryGap: [0.01, 0.01],
                        splitArea: { show: true }
                    }
                ],
                series: [
                    {
                        data: data.series,
                        type: 'line',
                        areaStyle:{},
                        smooth: true,
                    },
                ]
            };
            myChart.setOption(option);
        });
    }
});
/**
 * 下拉框选择
 */
$(".mode_code_args").click((e)=>{
    let button = $("#modal_mode_code")[0];
    button.value = e.target.attributes.value.value;
    button.innerText = e.target.text;

});
/**
 * 下拉框选择
 */
$(".mode_time_args").click((e)=>{
    let button = $("#modal_mode_time")[0];
    button.value = e.target.attributes.value.value;
    button.innerText = e.target.text;
    let mode = button.value;
    if (mode === 'history') {
        $("#modal_mode_time_args1").val("2018-01-01");
        $("#modal_mode_time_args2").val("2018-06-01");
    }else if(mode === 'random'){
        $("#modal_mode_time_args1").val("2018-01-01");
        $("#modal_mode_time_args2").val("100");
    }else{
        $("#modal_mode_time_args1").val("100");
        $("#modal_mode_time_args2").val("请不要输入任何东西");
    }
});


function ShowCharts(id, data){
    let myChart = echarts.init(document.getElementById(id));
    let option = {
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                type: 'cross',
                label: {
                    backgroundColor: '#283b56'
                }
            }
        },
        toolbox: {
            show: true,
            feature: {
                dataView: {readOnly: false},
                restore: {},
                saveAsImage: {}
            }
        },
        xAxis: {
            type: 'category',
            data: data.data.date
        },
        yAxis: [
            {
                type: 'value',
                scale: true,
                name: "账户市值",
                precision: 2,
                splitNumber: 9,
                boundaryGap: [0.01, 0.01],
                splitArea: { show: true }
            }
        ],
        series: [
            {
                data: data.data.money,
                type: 'line',
                areaStyle:{},
                smooth: true,
            },
        ]
    };
    myChart.setOption(option);
    ShowMultiLineChart("chart_market", data.data.market, data.data.date,(x)=>{
        return x.split(',')[2];
    }, (code, values)=>{
        let point = [];
        for (let i in data.data.flag[code]){
            switch (data.data.flag[code][i]){
                case '+':
                    point.push({ symbolRotate:180, symbol:'arrow', value:'+', xAxis: data.data.date[i], yAxis: values[i], symbolSize: [10, 15], itemStyle: {color: '#6091c1'} });
                    break;
                case '-':
                    point.push({ symbolRotate:0, symbol:'arrow', value:'-', xAxis: data.data.date[i], yAxis: values[i], symbolSize: [10, 15], itemStyle: {color: 'green'} });
                    break
            }
        }
        return {
            name: code,
            type:'line',
            smooth: true,
            data: values,
            markPoint: {
                data: point
            }
        }
    });
    ShowMultiLineChart("chart_pass", data.data.pass, data.data.date,(x)=>{
        return parseInt(x);
    }, (code, values)=>{
        return {
            name: code,
            type:'line',
            smooth: true,
            data: values,
        }
    });
}
function FlushMarchResult(args, count) {
    setTimeout(()=>{
        $.post(`/config/get_match/`, args, (res)=> {
            $("#match_area").css("display", "inline");
            for (let row of res){
                let data = $.parseJSON(row);
                count -= 1;
                $("#match_code").append(`<li><a data='${row}' id="match_code_${data.code}">${data.code}</a></li>`);
                $(`#match_code_${data.code}`).click((e)=>{
                    let item = e.target;
                    $("#match_show_code").val(item.text);
                    ShowCharts('chart', $.parseJSON(item.attributes.data.value));
                });
            }
            if (count > 0){
                FlushMarchResult(args, count);
            }
        });
    }, 1000);
}
function FlushSimulationResult(args){
    setTimeout(()=>{
        $.post(`/config/get_simulate/`, args, (data)=> {
            switch (data.ret) {
                case true:
                    console.log(data);
                    ShowCharts('chart', data);
                    $("#quota_area").css("display", "inline");
                    ShowQuotaMultiLineChart(data.data.quota, data.data.date);
                    SetTable(data.data.total);
                    break;
                case false:
                    if (data.msg.indexOf("error") !== -1){
                        return;
                    }else{
                        FlushSimulationResult(args);
                    }
                    break;
            }
        });
    }, 1000);
}
function SetTable(total){
    $("#table").css("display", "inline");
    $("#t_alm")[0].innerHTML = `￥${total.avg_loss_money}`;
    $("#t_apm")[0].innerHTML = `￥${total.avg_profit_money}`;
    $("#t_bc")[0].innerHTML = total.buy_count;
    $("#t_bp")[0].innerHTML = total.buy_position;
    $("#t_sc")[0].innerHTML = total.sell_count;
    $("#t_sp")[0].innerHTML = total.sell_position;
    $("#t_p")[0].innerHTML = `${total.profit}%`;
}
function ResetTable(){
    $("#table").css("display", "none");
    $("#t_alm")[0].innerHTML = "";
    $("#t_apm")[0].innerHTML = "";
    $("#t_bc")[0].innerHTML = "";
    $("#t_bp")[0].innerHTML = "";
    $("#t_sc")[0].innerHTML = "";
    $("#t_sp")[0].innerHTML = "";
    $("#t_p")[0].innerHTML = "";
}
function ShowQuotaMultiLineChart(quota, date) {
    for (let i in quota){
        $("#quota_code").append(`<li><a data='${JSON.stringify(quota[i])}' date='${JSON.stringify(date)}' id="quota_code_${i}">${i}</a></li>`);
        $(`#quota_code_${i}`).click((e)=>{
            let item = e.target;
            $("#quota_show_code").val(item.text);
            let data = $.parseJSON(item.attributes.data.value);
            let date = $.parseJSON(item.attributes.date.value);
            let series = [];
            let yAxis = [];
            for (let row = 0; row <= data.rows.length; row++){
                series.push({
                    name: data.label[row],
                    type:'line',
                    yAxisIndex: row,
                    smooth: true,
                    data: data.rows[row]
                });
                yAxis.push({
                    type: 'value',
                    scale: true,
                    show: false

                })
            }
            SetMultiLineChart("chart_quota", date, data.label, series, yAxis);
        });
    }
}
function SetMultiLineChart(chart_id, xAxis, labels, series, yAxis){
    let myChart = echarts.init(document.getElementById(chart_id));
    myChart.clear();
    let option = {
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                type: 'cross',
                label: {
                    backgroundColor: '#283b56'
                }
            }
        },
        toolbox: {
            show: true,
            feature: {
                dataView: {readOnly: false},
                restore: {},
                saveAsImage: {}
            }
        },
        legend: {
            data: labels
        },
        xAxis: {
            type: 'category',
            data: xAxis
        },
        yAxis: yAxis,
        series: series
    };
    myChart.setOption(option);
}
function ShowMultiLineChart(chart_id, datas, dates, value_format_func, series_format_func){
    let codes = [];
    let series = [];
    for (let code in datas){
        if (datas.hasOwnProperty(code)){
            codes.push(code);
            let values = [];
            for (let value of datas[code]){
                values.push(value_format_func(value));
            }
            series.push(series_format_func(code, values));
        }
    }
    SetMultiLineChart(chart_id, dates, codes, series, [ {
        type: 'value',
        scale: true,
    }]);
}
function GetModalData(){
    let code = $("#modal_text_code"),
        time1 = $("#modal_mode_time_args1"),
        time2 = $("#modal_mode_time_args2"),
        sell = $("#modal_sell"),
        buy = $("#modal_buy"),
        money = $("#modal_money"),
        strategy = $("#name_text"),
        formulas = $("#formula_text"),
        up = $("#modal_up"),
        down = $("#modal_down");
    try{
        code.validate("股票代码");
        time1.validate("时间参数1");
        time2.validate("时间参数2");
        sell.validate("默认出售通过率");
        buy.validate("默认购买通过率");
        money.validate("初始资金");
        strategy.validate("策略名称");
        formulas.validate("策略内容");
    }catch (err){
        return;
    }
    let args = {
        mode_code: {
            key: $('#modal_mode_code').val(),
            value: code.val()
        },
        mode_time: {
            key: $('#modal_mode_time').val(),
            value: time1.val() + ',' + time2.val()
        },
        buy_rate: buy.val(),
        sell_rate: sell.val(),
        up: up.val(),
        down: down.val(),
        money: money.val(),
        strategy: strategy.val(),
        formulas: formulas.val().replace(/\n/g, '|')
    };
    return args;
}
/**
 * 替换指定的文本框中的某个包含标识符的字符串，替换成新的
 * @param self: 文本框
 * @param text: 新字符串
 * @param sign: 被替换所包含的标识符
 */
function SetText(self, text, sign){
    let new_text = "";

    let bOnlyOnce = true;
    for (let line of self.value.split('\n')){
        if (new_text.length !== 0){
            new_text += '\n'
        }
        let new_line = "";
        for (let t of line.split(' ')){
            if (new_line.length !== 0){
                new_line += ' '
            }
            if (t.indexOf(sign) !== -1 && bOnlyOnce){
                new_line += text;
                bOnlyOnce = false;
            }else{
                new_line += t;
            }
        }
        new_text += new_line
    }
    self.value = new_text;
}
/**
 * 根据name_text判断读取哪张表，同时请求接口或者数据库数据
 *  1. 相应单机命令，切换数据到控件上（名称，公式）
 *  2. 更改按钮名称和修改按钮功能为(保存、清空、删除)
 */
function FlushTable(query_name=''){
    $("#formula_text")[0].value = "";
    $("#name_text")[0].value = "";
    $("#save_btn").removeAttr('data_id');

    let db = GetDBName();

    $.get(`/config/query/${db}/?query=${query_name}`, (res)=>{
        let table = $("#table_item");
        table[0].innerHTML = '';
        for (let item of res){
            table.append(`<button id="table_btn_${item.id}" style="width: 100%; border:0; background-color: #FFF" value="${item.formula.join('\n')}">${item.name}</button>`)
            $("#table_btn_" + item.id).click((e)=>{
                $("#name_text")[0].value = e.currentTarget.innerText;
                $("#formula_text")[0].value = e.currentTarget.value;
                $("#save_btn").attr("data_id", e.currentTarget.id.replace(/table_btn_/, ''));
            })
        }
    });
}
/**
 * 获取DB名称
 * @returns {*}
 */
function GetDBName(){
    let name = $("#addon_name")[0];
    if (name.innerText === '策略名称')
        return "strategy";
    else if (name.innerText === '指标名称')
        return 'quota';
    else
        return undefined;
}

{
    // FlushTable();
    // const renderDom = Component => {
    //     render(
    //         <App />,
    //         document.getElementById('container')
    //     );
    // };
    //
    // renderDom(App);
    render(<App />, document.getElementById('container'))
}